Skip to main content

Union structure

Sometimes a data structure is needed to represent different types of data for different occasions. For example, if only one data structure is used to represent the 'amount' of fruit, this structure needs to be sometimes an integer (6 apples) and sometimes a floating point number (1.5 kg of strawberries).

The C language provides the Union structure for customising data structures that can be changed flexibly. It can contain various attributes inside, but only one at a time, as all attributes are stored at the same memory address and attributes written later will overwrite the previous ones. The biggest advantage of this is that it saves space.

union quantity {
short count;
float weight;
float volume;
};

In the above example, the union command defines a data type quantity with three attributes. Although it contains three properties, only one property can be fetched at any one time. The last property to be assigned is the one whose value can be fetched.

To use it, declare a variable of this type.

// Write one
union quantity q;
q.count = 4;

// Write two
union quantity q = {.count=4};

// Write three
union quantity q = {4};

The above code shows three ways to assign a value to a Union structure. The last way, without specifying a property name, assigns the value to the first property.

After executing the above code, q.count will get the value, but the other two properties will not get the value.

printf("count is %i\n", q.count); // count is 4
printf("weight is %f\n", q.weight); // undefined behaviour

If you want the q.weight property to be fetchable, you have to assign a value to it first.

q.weight = 0.5;
printf("weight is %f\n", q.weight); // weight is 0.5

Once you assign values to other properties, the q.count property, which could have fetched a value, is no longer valid. Other than this, the usage of Union structures is essentially the same as Struct structures.

Union structures also support the pointer operator ->.

union quantity {
short count;
float weight;
float volume;
};

union quantity q;
q.count = 4;

union quantity* ptr;
ptr = &q;

printf("%d\n", ptr->count); // 4

In the above example, ptr is a pointer to q, so ptr->count is equivalent to q.count.

A pointer to a Union structure is related to its attributes, and whichever attribute can currently fetch a value, its pointer is the corresponding data type.

union foo {
int a;
float b;
} x;

int* foo_int_p = (int *)&x;
float* foo_float_p = (float *)&x;

x.a = 12;
printf("%d\n", x.a); // 12
printf("%d\n", *foo_int_p); // 12

x.b = 3.141592;
printf("%f\n", x.b); // 3.141592
printf("%f\n", *foo_float_p); // 3.141592

In the above example, &x is a pointer to the foo structure, and its data type is determined entirely by the currently assigned property.

The typedef command can be used to alias the Union data type.

typedef union {
short count;
float weight;
float volume;
} quantity;

In the above example, the union command defines a data type containing three attributes, which the typedef command aliases to quantity.

The main benefit of the union structure is that it saves space. It takes a section of memory space and reuses it for different types of data. The length of memory occupied by a Union structure is equal to the length of the longest property inside it.